package net.gxnun.xiaoyuan.core.entry;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.gxnun.xiaoyuan.core.annotaction.handler.MessageMappingHandler;
import net.gxnun.xiaoyuan.core.business.share.SessionManager;
import net.gxnun.xiaoyuan.core.business.share.UserSession;
import net.gxnun.xiaoyuan.core.message.handler.MessageHandler;
import net.gxnun.xiaoyuan.core.message.handler.impl.MenuErrorMessageHandler;
import net.gxnun.xiaoyuan.core.message.handler.impl.MenuMessageHandler;
import net.gxnun.xiaoyuan.core.message.request.RequestMsg;
import net.gxnun.xiaoyuan.core.message.request.TextMsg;
import net.gxnun.xiaoyuan.core.message.request.WebsiteJoinMsg;
import net.gxnun.xiaoyuan.core.message.response.ResponseModel;
import net.gxnun.xiaoyuan.core.share.ApplicationContextHolder;
import net.gxnun.xiaoyuan.core.share.MsgType;
import net.gxnun.xiaoyuan.core.share.TextPrefix;
import net.gxnun.xiaoyuan.core.share.XmlToMessage;
import net.gxnun.xiaoyuan.core.utils.MyStringUtils;
import net.gxnun.xiaoyuan.message.handler.WebSiteJoinBusiness;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;

/**
 * 入口Servlet
 * @author yesheng
 *
 */
public class XiaoyuanServlet extends HttpServlet {

    private Logger log = Logger.getLogger(XiaoyuanServlet.class);
    
    private static final long serialVersionUID = 1L;
    private static final String token = "yesheng";
    private WebSiteJoinBusiness webSiteJoinBusiness;
    
    private MessageMappingHandler messageMappingHandler ;
    private MenuErrorMessageHandler menuErrorMessageHandler;
    private MenuMessageHandler menuMessageHandler;

    

    @Override
    public void init() throws ServletException {
        super.init();
        ApplicationContext context = ApplicationContextHolder.getApplicationContext();
        messageMappingHandler = context.getBean(MessageMappingHandler.class);
        menuErrorMessageHandler = context.getBean(MenuErrorMessageHandler.class);
        menuMessageHandler = context.getBean(MenuMessageHandler.class);
        webSiteJoinBusiness = context.getBean(WebSiteJoinBusiness.class);
    }
    
    /**
     * doGet只处理网站接入请求。
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        log.debug("get请求！");
        
        PrintWriter out = response.getWriter();
        
        WebsiteJoinMsg msg = new WebsiteJoinMsg();
        msg.setEchostr(request.getParameter("echostr"));
        msg.setNonce(request.getParameter("nonce"));
        msg.setSignature(request.getParameter("signature"));
        msg.setTimestamp(request.getParameter("timestamp"));
        
        
        //检查变量
        if(msg.getEchostr()==null || msg.getEchostr().equals("")
           || msg.getNonce()==null || msg.getNonce().equals("")
           || msg.getSignature()==null || msg.getSignature().equals("")
           || msg.getTimestamp()==null || msg.getTimestamp().equals("")){
            return ;
        }
        //按照标准检查
        if(webSiteJoinBusiness.checkJoinMsg(msg, token)){
            log.debug("msg:"+msg);
            out.println(msg.getEchostr());
        }else{
            log.debug("验证不通过！");
        }
        
        out.flush();
        out.close();
        
    }

    /**
     * doPost处理所有XML请求
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        //设置编码
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml");
        PrintWriter out = response.getWriter();

        //提取post的xml内容
        String buff = "";
        StringBuffer xmlsb = new StringBuffer();
        while((buff=request.getReader().readLine())!=null){
            xmlsb.append(buff);
        }
        
        log.debug(xmlsb.toString());

        //获得消息的类型
        String type = MyStringUtils.getWordByReg("(?<=<MsgType><!\\[CDATA\\[).*(?=]]></MsgType>)"
                                            , xmlsb.toString());
        //获得用户ID
        String fromUserName = MyStringUtils.getWordByReg("(?<=<FromUserName><!\\[CDATA\\[).*(?=]]></FromUserName>)"
                                            , xmlsb.toString());
        
        //如果消息类型为文本，则：
        //如果文本是目录，那么就交给目录处理器处理，如果文本是具体的内容，那么就交给具体的业务处理器处理.
        
        ResponseModel responseModel = null; 
        UserSession session = SessionManager.getInstance().getSession(fromUserName);
        String url = (String)session.getAttribute("url");
        
        
        if(type.equals(MsgType.Text)){
            log.debug("这是文本消息！");
            TextMsg msg = (TextMsg)XmlToMessage.parseMsg(xmlsb.toString(), type);
            String content = msg.getContent();
            //如果是进入目录的话
            if(content.startsWith(TextPrefix.getTextPrefix("menu"))){
                log.debug("请求目录！");
                String menuStr = content.substring(1);
                //如果不存在这个目录，则交给目录错误处理器进行处理
                if(menuStr == null || messageMappingHandler.getMessageHandler(menuStr)==null){
                    log.debug("不存在该目录！");
                    responseModel = menuErrorMessageHandler.handler(msg);
                    return ;
                }
                log.debug("进入和处理目录！");
                session.setAttribute("url", content);
                responseModel = menuMessageHandler.handler(msg);
                return;
            }
        }
        
        log.debug("其他信息！");
        //如果消息类型为其他媒体，则：获取当前用户的位置，交给对应的业务处理器。
        RequestMsg msg = XmlToMessage.parseMsg(xmlsb.toString(), type);
        MessageHandler handler = messageMappingHandler.getMessageHandler(url);
        String allowType = messageMappingHandler.getAllowType(url);
        
        if(allowType.contains(type)){
            log.debug("处理信息");
            responseModel = handler.handler(msg);
        }
        else{
            log.debug("处理非法信息");
            responseModel = menuErrorMessageHandler.handler(msg);
        }
        
        out.println(responseModel.toXml());
        
        out.flush();
        out.close();
    }


}
